package com.example.gateway.configuration;

import com.alibaba.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingFactory;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.listener.NamingEvent;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.netflix.loadbalancer.ServerListUpdater;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.common.utils.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

/**
 * @author DestinyCc
 * @date 2022/4/15
 */
@Component
@Slf4j
public class ServerStatusListener {
    @Autowired
    private CustomPollingServerListUpdater serverListUpdater;

    @Value("${spring.cloud.nacos.discovery.namespace}")
    private String namespace;
    @Value("${spring.cloud.nacos.discovery.server-addr}")
    private String serverAddr;

    @PostConstruct
    public void init() throws Exception {
        //初始化监听服务上下线
        Properties properties = System.getProperties();
        properties.put(PropertyKeyConst.NAMESPACE, namespace);
        properties.put(PropertyKeyConst.SERVER_ADDR, serverAddr);

        NamingService naming = NamingFactory.createNamingService(properties);

        List<String> serviceNames = new ArrayList<>();
        // 要监听的服务名称
        serviceNames.add("auth-service");
        serviceNames.add("callback-service");
        serviceNames.add("code-quality-service");
        serviceNames.add("diff-service");
        serviceNames.add("gateway-service");
        serviceNames.forEach(serviceName->{
            try {
                naming.subscribe(serviceName, (event -> {
                    //通知ribbon更新服务列表
                    ServerListUpdater.UpdateAction updateAction = serverListUpdater.getUpdateAction();
                    if (updateAction != null){
                        updateAction.doUpdate();
                    }
                    NamingEvent namingEvent = (NamingEvent) event;
                    List<Instance> instances = namingEvent.getInstances();
                    String name = namingEvent.getServiceName();
                    if(CollectionUtils.isNotEmpty(instances)){
                        instances.forEach(instance -> log.info("服务[serviceName = {}, namingEvent.getServiceName() = {}] : {}", serviceName, name, instance));
                    }else {
                        log.warn("服务 = {} 列表为空", name);
                    }
                }));
            } catch (NacosException e) {
                log.error("ServerStatusListener 失败，msg = {}", e.toString());
            }
        });
    }
}
